package mx.ipn.persistencia.mysql;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;

import mx.ipn.persistencia.FabricaDeDAOs;
import mx.ipn.persistencia.dao.TarjetaDAO;
import mx.ipn.persistencia.dao.TipoTarjetaDAO;
import mx.ipn.persistencia.dao.InstitucionFinancieraDAO;
import mx.ipn.to.TarjetaTO;
import mx.ipn.to.TipoTarjetaTO;
import mx.ipn.to.InstitucionFinancieraTO;
import mx.ipn.to.FechaHoraTO;

public class TarjetaDAOMySQL implements TarjetaDAO {
	static{FabricaDeDAOsMySQL.iniciaLog(TarjetaDAOMySQL.class);}

	private static final String LLAVE = "llavetarjeta";

	private static final String INSERT = "INSERT INTO tarjeta (numero,codigo_seguridad,fecha_vencimiento,id_institucion_financiera,id_tipo_tarjeta) VALUES(aes_encrypt(?,'"
			+ LLAVE + "'),aes_encrypt(?,'" + LLAVE + "'),?,?,?)";
	private static final String UPDATE = "UPDATE tarjeta SET numero=aes_encrypt(?,'"
			+ LLAVE
			+ "'),codigo_seguridad=aes_encrypt(?,'"
			+ LLAVE
			+ "'),fecha_vencimiento=?,id_institucion_financiera=?,id_tipo_tarjeta=? WHERE id_tarjeta=?";
	private static final String FINDBYID = "SELECT * FROM tarjeta WHERE id_tarjeta=?";
	private static final String FINDBYNUMEROINSTITUCION = "SELECT * FROM tarjeta WHERE numero=aes_encrypt(?,'"
			+ LLAVE + "') AND id_institucion_financiera=?";
	private static final String SELECT = "SELECT * FROM tarjeta";
	private static final String SELECTBYRANGOFECHA = "SELECT * FROM tarjeta WHERE fecha_vencimiento>=? AND fecha_vencimiento<=?";
	private static final String SELECTBYINSTITUCIONFINANCIERA = "SELECT * FROM tarjeta WHERE id_institucion_financiera=?";
	private static final String SELECTBYTIPOTARJETA = "SELECT * FROM tarjeta WHERE id_tipo_tarjeta=?";

	@Override
	public TarjetaTO findTarjetaById(int idTarjeta) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(FINDBYID);

			ps.setInt(1, idTarjeta);

			ResultSet rs = ps.executeQuery();

			if (rs.next()) {

				
				FabricaDeDAOs fabricaMySQL = FabricaDeDAOs
						.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);
				
				InstitucionFinancieraDAO institucionFinancieraDAO = fabricaMySQL
						.getInstitucionFinancieraDAO();
				TipoTarjetaDAO tipoTarjetaDAO = fabricaMySQL
						.getTipoTarjetaDAO();

				TarjetaTO tarjetaTO = new TarjetaTO(idTarjeta, rs
						.getString("numero"), rs.getString("codigo_seguridad"),
						rs.getDate("fecha_vencimiento"),
						institucionFinancieraDAO
								.findInstitucionFinancieraById(rs
										.getInt("id_institucion_financiera")),
						tipoTarjetaDAO.findTipoTarjetaById(rs
								.getShort("id_tipo_tarjeta")));

				ps.close();
				conexion.close();
				return tarjetaTO;
			}

			ps.close();
			conexion.close();
			return null;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public TarjetaTO findTarjetaByNumeroInstitucion(String numero,
			int idInstitucionFinanciera) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion
					.prepareStatement(FINDBYNUMEROINSTITUCION);

			ps.setString(1, numero);
			ps.setInt(2, idInstitucionFinanciera);

			ResultSet rs = ps.executeQuery();

			if (rs.next()) {

				
				FabricaDeDAOs fabricaMySQL = FabricaDeDAOs
						.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);
				
				InstitucionFinancieraDAO institucionFinancieraDAO = fabricaMySQL
						.getInstitucionFinancieraDAO();
				TipoTarjetaDAO tipoTarjetaDAO = fabricaMySQL
						.getTipoTarjetaDAO();

				TarjetaTO tarjetaTO = new TarjetaTO(rs.getInt("id_tarjeta"), rs
						.getString("numero"), rs.getString("codigo_seguridad"),
						rs.getDate("fecha_vencimiento"),
						institucionFinancieraDAO
								.findInstitucionFinancieraById(rs
										.getInt("id_institucion_financiera")),
						tipoTarjetaDAO.findTipoTarjetaById(rs
								.getShort("id_tipo_tarjeta")));

				ps.close();
				conexion.close();
				return tarjetaTO;
			}

			ps.close();
			conexion.close();
			return null;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public boolean insertTarjeta(TarjetaTO tarjetaTO) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(INSERT);

			ps.setString(1, tarjetaTO.getNumero());
			ps.setString(2, tarjetaTO.getCodigoSeguridad());
			ps.setDate(3, FechaHoraTO.getFecha(tarjetaTO.getFechaVencimiento()));
			ps.setInt(4, tarjetaTO.getInstitucionFinancieraTO()
					.getIdInstitucionFinanciera());
			ps.setShort(5, tarjetaTO.getTipoTarjetaTO().getIdTipoTarjeta());
			ps.executeUpdate();

			ps.close();
			conexion.close();

			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	@Override
	public ArrayList<TarjetaTO> selectTarjeta() {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			FabricaDeDAOs fabricaMySQL = FabricaDeDAOs
					.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);

			InstitucionFinancieraDAO institucionFinancieraDAO = fabricaMySQL
					.getInstitucionFinancieraDAO();
			TipoTarjetaDAO tipoTarjetaDAO = fabricaMySQL.getTipoTarjetaDAO();

			ArrayList<TarjetaTO> tarjetaTO = null;
			TarjetaTO tarjetaTO2 = null;

			PreparedStatement ps = conexion.prepareStatement(SELECT);

			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				if (tarjetaTO == null) {
					tarjetaTO = new ArrayList<TarjetaTO>();

					institucionFinancieraDAO = fabricaMySQL
							.getInstitucionFinancieraDAO();
					tipoTarjetaDAO = fabricaMySQL.getTipoTarjetaDAO();
				}

				int idTarjeta = rs.getInt("id_tarjeta");
				String numero = rs.getString("numero");
				String codigo = rs.getString("codigo_seguridad");
				java.sql.Date fecha = rs.getDate("fecha_vencimiento");

				tarjetaTO2 = new TarjetaTO(idTarjeta, numero, codigo, fecha,
						institucionFinancieraDAO
								.findInstitucionFinancieraById(rs
										.getInt("id_institucion_financiera")),
						tipoTarjetaDAO.findTipoTarjetaById(rs
								.getShort("id_tipo_tarjeta")));

				tarjetaTO.add(tarjetaTO2);
			}
			ps.close();
			conexion.close();
			return tarjetaTO;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public ArrayList<TarjetaTO> selectTarjetaByRangoFecha(Date inicioFecha,
			Date finFecha) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			FabricaDeDAOs fabricaMySQL = null;

			InstitucionFinancieraDAO institucionFinancieraDAO = null;
			TipoTarjetaDAO tipoTarjetaDAO = null;

			ArrayList<TarjetaTO> tarjetaTO = null;
			TarjetaTO tarjetaTO2 = null;

			PreparedStatement ps = conexion
					.prepareStatement(SELECTBYRANGOFECHA);
			ps.setDate(1, inicioFecha);
			ps.setDate(2, finFecha);
			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				if (tarjetaTO == null) {
					tarjetaTO = new ArrayList<TarjetaTO>();
					fabricaMySQL = FabricaDeDAOs
							.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);
					institucionFinancieraDAO = fabricaMySQL
							.getInstitucionFinancieraDAO();
					tipoTarjetaDAO = fabricaMySQL.getTipoTarjetaDAO();
				}

				tarjetaTO2 = new TarjetaTO(rs.getInt("id_tarjeta"), rs
						.getString("numero"), rs.getString("codigo_seguridad"),
						rs.getDate("fecha_vencimiento"),
						institucionFinancieraDAO
								.findInstitucionFinancieraById(rs
										.getInt("id_institucion_financiera")),
						tipoTarjetaDAO.findTipoTarjetaById(rs
								.getShort("id_tipo_tarjeta")));

				tarjetaTO.add(tarjetaTO2);
			}
			ps.close();
			conexion.close();
			return tarjetaTO;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public TarjetaTO selectTarjetaByInstitucionFinanciera(
			int idInstitucionFinanciera) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();
			
			FabricaDeDAOs fabricaMySQL = null;
			
			InstitucionFinancieraDAO institucionFinancieraDAO = null;
			TipoTarjetaDAO tipoTarjetaDAO = null;

			ArrayList<Integer> listIdTarjeta = null;
			ArrayList<String> listNumero = null;
			ArrayList<String> listCodigo = null;
			ArrayList<java.sql.Date> listFecha = null;
			ArrayList<TipoTarjetaTO> listTipoTarjetaTO = null;

			TarjetaTO tarjetaTO = null;

			PreparedStatement ps = conexion
					.prepareStatement(SELECTBYINSTITUCIONFINANCIERA);
			ps.setInt(1, idInstitucionFinanciera);
			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				if (listIdTarjeta == null) {

					listIdTarjeta = new ArrayList<Integer>();
					listNumero = new ArrayList<String>();
					listCodigo = new ArrayList<String>();
					listFecha = new ArrayList<java.sql.Date>();
					listTipoTarjetaTO = new ArrayList<TipoTarjetaTO>();
					fabricaMySQL = FabricaDeDAOs
							.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);

					institucionFinancieraDAO = fabricaMySQL
							.getInstitucionFinancieraDAO();
					tipoTarjetaDAO = fabricaMySQL.getTipoTarjetaDAO();
				}

				listIdTarjeta.add(rs.getInt("id_tarjeta"));
				listNumero.add(rs.getString("numero"));
				listCodigo.add(rs.getString("codigo_seguridad"));
				listFecha.add(rs.getDate("fecha_vencimiento"));
				listTipoTarjetaTO.add(tipoTarjetaDAO.findTipoTarjetaById(rs
						.getShort("id_tipo_tarjeta")));
			}
			if (listIdTarjeta != null) {

				Date[] arrFecha = (Date[]) listFecha.toArray(new Date[listFecha
						.size()]);
				String[] arrNumero = (String[]) listNumero
						.toArray(new String[listNumero.size()]);
				String[] arrCodigo = (String[]) listCodigo
						.toArray(new String[listCodigo.size()]);
				Integer[] arrIdTarjeta = (Integer[]) listIdTarjeta
						.toArray(new Integer[listIdTarjeta.size()]);
				TipoTarjetaTO[] arrTipoTarjetaTO = (TipoTarjetaTO[]) listTipoTarjetaTO
						.toArray(new TipoTarjetaTO[listTipoTarjetaTO.size()]);

				tarjetaTO = new TarjetaTO(
						arrIdTarjeta,
						arrNumero,
						arrCodigo,
						arrFecha,
						institucionFinancieraDAO
								.findInstitucionFinancieraById(idInstitucionFinanciera),
						arrTipoTarjetaTO);

			}
			ps.close();
			conexion.close();
			return tarjetaTO;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public TarjetaTO selectTarjetaByTipoTrajeta(short idTipoTarjeta) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();
			
			FabricaDeDAOs fabricaMySQL = null;
			
			InstitucionFinancieraDAO institucionFinancieraDAO = null;
			TipoTarjetaDAO tipoTarjetaDAO = null;

			ArrayList<Integer> listIdTarjeta = null;
			ArrayList<String> listNumero = null;
			ArrayList<String> listCodigo = null;
			ArrayList<java.sql.Date> listFecha = null;
			ArrayList<InstitucionFinancieraTO> listInstitucionFinancieraTO = null;

			TarjetaTO tarjetaTO = null;

			PreparedStatement ps = conexion
					.prepareStatement(SELECTBYTIPOTARJETA);
			ps.setInt(1, idTipoTarjeta);
			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				if (listIdTarjeta == null) {

					listIdTarjeta = new ArrayList<Integer>();
					listNumero = new ArrayList<String>();
					listCodigo = new ArrayList<String>();
					listFecha = new ArrayList<java.sql.Date>();
					listInstitucionFinancieraTO = new ArrayList<InstitucionFinancieraTO>();
					fabricaMySQL = FabricaDeDAOs
							.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);

					institucionFinancieraDAO = fabricaMySQL
							.getInstitucionFinancieraDAO();
					tipoTarjetaDAO = fabricaMySQL.getTipoTarjetaDAO();
				}

				listIdTarjeta.add(rs.getInt("id_tarjeta"));
				listNumero.add(rs.getString("numero"));
				listCodigo.add(rs.getString("codigo_seguridad"));
				listFecha.add(rs.getDate("fecha_vencimiento"));
				listInstitucionFinancieraTO.add(institucionFinancieraDAO
						.findInstitucionFinancieraById(rs
								.getInt("id_institucion_financiera")));
			}
			if (listIdTarjeta != null) {

				Date[] arrFecha = (Date[]) listFecha.toArray(new Date[listFecha
						.size()]);
				String[] arrNumero = (String[]) listNumero
						.toArray(new String[listNumero.size()]);
				String[] arrCodigo = (String[]) listCodigo
						.toArray(new String[listCodigo.size()]);
				Integer[] arrIdTarjeta = (Integer[]) listIdTarjeta
						.toArray(new Integer[listIdTarjeta.size()]);
				InstitucionFinancieraTO[] arrInstitucionFinancieraTO = (InstitucionFinancieraTO[]) listInstitucionFinancieraTO
						.toArray(new InstitucionFinancieraTO[listInstitucionFinancieraTO
								.size()]);

				tarjetaTO = new TarjetaTO(arrIdTarjeta, arrNumero, arrCodigo,
						arrFecha, arrInstitucionFinancieraTO, tipoTarjetaDAO
								.findTipoTarjetaById(idTipoTarjeta));
			}
			ps.close();
			conexion.close();
			return tarjetaTO;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public short updateTarjeta(TarjetaTO tarjetaTO) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(UPDATE);

			ps.setString(1, tarjetaTO.getNumero());
			ps.setString(2, tarjetaTO.getCodigoSeguridad());
			ps.setDate(3, FechaHoraTO.getFecha(tarjetaTO.getFechaVencimiento()));
			ps.setInt(4, tarjetaTO.getInstitucionFinancieraTO()
					.getIdInstitucionFinanciera());
			ps.setShort(5, tarjetaTO.getTipoTarjetaTO().getIdTipoTarjeta());
			ps.setInt(6, tarjetaTO.getIdTarjeta());

			ps.executeUpdate();

			if (ps.getUpdateCount() == 0) {
				ps.close();
				conexion.close();
				return 0;
			} else {
				ps.close();
				conexion.close();
				return 1;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return (short) -1;
		}
	}

}
